/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package net.sf.l2j.gameserver.custom.events;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.Announcements;
import net.sf.l2j.gameserver.custom.events.engine.EventState;
import net.sf.l2j.gameserver.custom.events.engine.EventType;
import net.sf.l2j.gameserver.custom.events.engine.IEvent;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.skills.AbnormalEffect;

/**
 * @author Anarchy
 *
 */
public class DeathmatchEvent implements IEvent
{
	private static final Logger _log = Logger.getLogger(DeathmatchEvent.class.getName());
	
	private Map<L2PcInstance, Integer> _players;
	private EventState _state = EventState.INACTIVE;
	
	public DeathmatchEvent()
	{
		_log.info("Deathmatch Event loaded.");
		_players = new HashMap<>();
	}
	
	@Override
	public void runEvent()
	{
		Announcements.announceToAll("Registrations for the Deathmatch Event have opened for 5 minutes. Type .join to register and .leave to unregister.");
		_state = EventState.REGISTERING;
		
		sleep(60*2);
		
		if (!check())
		{
			return;
		}
		
		Announcements.announceToAll("Registrations for the Deathmatch Event have closed. Players will be teleported in 10 seconds.");
		_state = EventState.RUNNING;
		
		sleep(10);
		
		teleportAndParalize();
		Announcements.announceToAll("The players have been teleported. Fight begins in 5 seconds.");
		
		sleep(5);
		
		unpara();
		Announcements.announceToAll("The fight has started!");
		Announcements.announceToAll("The event will end in 5 minutes.");
		
		sleep(2*60);
		
		rewardAndClear();
		_state = EventState.INACTIVE;
	}
	
	public void addPoint(L2PcInstance p)
	{
		int i = _players.get(p);
		
		_players.remove(p);
		
		_players.put(p, i++);
	}
	
	public void rewardAndClear()
	{
		int i = 0;
		L2PcInstance c = null;
		for (L2PcInstance p : _players.keySet())
		{
			p.teleToLocation(Config.EVENT_END_LOCATION[0], Config.EVENT_END_LOCATION[1], Config.EVENT_END_LOCATION[2], 1);
			
			p.setInEvent(false);
			
			if (_players.get(p) > i)
			{
				i = _players.get(p);
				c = p;
			}
		}
		
		if (i > 0 && c != null)
		{
			for (int q : Config.DEATHMATCH_EVENT_REWARDS.keySet())
			{
				c.addItem("VR", q, Config.DEATHMATCH_EVENT_REWARDS.get(q), c, true);
			}
			c.sendMessage("You have won the event!");
			Announcements.announceToAll("The event ended with "+c.getName()+" as the winner!");
		}
		else
		{
			Announcements.announceToAll("The event ended with no winner.");
		}
		
		_players.clear();
	}
	
	public void unpara()
	{
		for (L2PcInstance p : _players.keySet())
		{
			p.stopAbnormalEffect(AbnormalEffect.ROOT);
			p.setIsParalyzed(false);
		}
	}
	
	public void teleportAndParalize()
	{
		for (L2PcInstance p : _players.keySet())
		{
			p.teleToLocation(Config.DEATHMATCH_LOCATION[0], Config.DEATHMATCH_LOCATION[1], Config.DEATHMATCH_LOCATION[2], 1);
			p.startAbnormalEffect(AbnormalEffect.ROOT);
			p.setIsParalyzed(true);
			p.sendMessage("You have been teleported.");
		}
	}
	
	public boolean check()
	{
		if (_players.size() < 3)
		{
			Announcements.announceToAll("The event was cancelled due to lack of participation.");
			for (L2PcInstance p : _players.keySet())
			{
				p.setInEvent(false);
			}
			_players.clear();
			_state = EventState.INACTIVE;
			return false;
		}
		
		return true;
	}
	
	public void sleep(int seconds)
	{
		try
		{
			Thread.sleep(seconds*1000);
		}
		catch (InterruptedException e)
		{ }
	}

	@Override
	public void registerPlayer(L2PcInstance p, Object...args)
	{
		if (getState() != EventState.REGISTERING)
		{
			p.sendMessage("You cannot register for the event right now.");
			return;
		}
		
		if (_players.keySet().contains(p))
		{
			p.sendMessage("You have already registered for the event.");
			return;
		}
		
		_players.put(p, 1);
		p.setInEvent(true);
		p.sendMessage("You have successfully registered for the event.");
	}

	@Override
	public void removePlayer(L2PcInstance p)
	{
		if (getState() != EventState.REGISTERING)
		{
			p.sendMessage("You cannot remove your participation from the event right now.");
			return;
		}
		
		if (!_players.keySet().contains(p))
		{
			p.sendMessage("You have not registered for the event.");
			return;
		}
		
		_players.remove(p);
		p.setInEvent(false);
		p.sendMessage("You have successfully removed your participation from the event.");
	}

	@Override
	public String getTimes()
	{
		return Config.DEATHMATCH_EVENT_TIMES;
	}

	@Override
	public EventType getType()
	{
		return EventType.NORMAL;
	}

	@Override
	public EventState getState()
	{
		return _state;
	}

	@Override
	public boolean containsPlayer(L2PcInstance p)
	{
		return _players.keySet().contains(p);
	}
}